package ru.alt22.visor.php.ui.actions;

import java.util.ArrayList;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuCreator;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowPulldownDelegate2;
import org.eclipse.ui.PlatformUI;

public class NewTypeDropDownAction extends Action implements IMenuCreator, IWorkbenchWindowPulldownDelegate2 {
	
	private final static String TAG_WIZARD = "wizard";//$NON-NLS-1$
	private final static String ATT_PHPTYPE = "phptype";//$NON-NLS-1$
	
	private final static String TAG_PARAMETER = "parameter";//$NON-NLS-1$
	private final static String TAG_NAME = "name";//$NON-NLS-1$
	private final static String TAG_VALUE = "value";//$NON-NLS-1$
	
	private static final String PL_NEW = "newWizards"; //$NON-NLS-1$
	private static final String TAG_CLASS = "class"; //$NON-NLS-1$
	
	private Menu menu;
	private Shell wizardShell;
	private IStructuredSelection currentSelection; 

	public NewTypeDropDownAction() {
		menu = null;
		setMenuCreator(this);
	}

	public void dispose() {
		if (menu != null) {
			menu.dispose();
			menu = null;
		}
	}

	public Menu getMenu(Control parent) {
		if (menu == null) {
			menu = new Menu(parent);
			NewTypeWizardAction[] actions = getActionFromDescriptors();
			for (int i = 0; i < actions.length; i++) {
				NewTypeWizardAction action = actions[i];
				action.setShell(wizardShell);
				action.setSelection(currentSelection);
				ActionContributionItem item = new ActionContributionItem(action);
				item.fill(menu, -1);				
			}
		}
		return menu;
	}

	public Menu getMenu(Menu parent) {
		return null;
	}

	public static NewTypeWizardAction[] getActionFromDescriptors() {
		ArrayList<NewTypeWizardAction> containers = new ArrayList<NewTypeWizardAction>();
		
		IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(PlatformUI.PLUGIN_ID, PL_NEW);
		if (extensionPoint != null) {
			IConfigurationElement[] elements = extensionPoint.getConfigurationElements();
			for (int i = 0; i < elements.length; i++) {
				IConfigurationElement element = elements[i];
				if (element.getName().equals(TAG_WIZARD) && isPhpTypeWizard(element)) {
					containers.add(new NewTypeWizardAction(element));
				}
			}
		}
		
		return (NewTypeWizardAction[]) containers.toArray(new NewTypeWizardAction[containers.size()]);
	}

	private static boolean isPhpTypeWizard(IConfigurationElement element) {
		IConfigurationElement[] classElements = element.getChildren(TAG_CLASS);
		if (classElements.length > 0) {
			for (int i = 0; i < classElements.length; i++) {
				IConfigurationElement[] paramElements = classElements[i].getChildren(TAG_PARAMETER);
				for (int k = 0; k < paramElements.length; k++) {
					IConfigurationElement curr = paramElements[k];
					if (ATT_PHPTYPE.equals(curr.getAttribute(TAG_NAME))) {
						return Boolean.valueOf(curr.getAttribute(TAG_VALUE)).booleanValue();
					}
				}
			}
		}
		// old way, deprecated
		if (Boolean.valueOf(element.getAttribute(ATT_PHPTYPE)).booleanValue()) {
			return true;
		}
		return false;
	}

	public void init(IWorkbenchWindow window) {
		wizardShell = window.getShell();
	}

	public void run() {
		NewClassWizardAction action = new NewClassWizardAction();
		action.setSelection(currentSelection);
		action.run();
	}

	public void run(IAction action) {
		run();
	}

	public void selectionChanged(IAction action, ISelection selection) {
		if (selection == null || selection.isEmpty() == true || !(selection instanceof IStructuredSelection)) {
			return;
		}
		currentSelection = (IStructuredSelection) selection;
		if (menu != null) {
			for (int i = 0; i < menu.getItemCount(); i++) {
				ActionContributionItem menuItem = (ActionContributionItem) menu.getItem(i).getData();
				NewTypeWizardAction menuAction = (NewTypeWizardAction) menuItem.getAction();
				menuAction.setSelection(currentSelection);
			}
		}
	}

}